#!/usr/bin/env python
import time
import sys
import Optical_Transmitter as transmitter

transmitter.init()

# Morse code:
# symbols:
# '.' dit, length = 1 * dit
# '-' Dah, length = 3 * dit
#
# break between symbols: 1 dit
# break between characters: 3 dits
# break between words: 7 dits


# Dicitionary of Morse codes for: ( ) + , - . / 0 ... 9 : ; = ? @ A ... Z
code = {'(':[3,1,3,3,1],')':[3,1,3,3,1,3],'+':[1,3,1,3,1],',':[3,3,1,1,3,3],'-':[3,1,1,1,1,3],'.':[1,3,1,3,1,3],'/':[3,1,1,3,1],'0':[3,3,3,3,3],'1':[1,3,3,3,3],'2':[1,1,3,3,3],'3':[1,1,1,3,3],'4':[1,1,1,1,3],'5':[1,1,1,1,1],'6':[3,1,1,1,1],'7':[3,3,1,1,1],'8':[3,3,3,1,1],'9':[3,3,3,3,1],':':[3,3,3,1,1,1],';':[3,1,3,1,3,1],'=':[3,1,1,1,3],'?':[1,1,3,3,1,1],'@':[1,3,3,1,3,1],'A':[1,3],'B':[3,1,1,1],'C':[3,1,3,1],'D':[3,1,1],'E':[1],'F':[1,1,3,1],'G':[3,3,1],'H':[1,1,1,1],'I':[1,1],'J':[1,3,3,3],'K':[3,1,3],'L':[1,3,1,1],'M':[3,3],'N':[3,1],'O':[3,3,3],'P':[1,3,3,1],'Q':[3,3,1,3],'R':[1,3,1],'S':[1,1,1],'T':[3],'U':[1,1,3],'V':[1,1,1,3],'W':[1,3,3],'X':[3,1,1,3],'Y':[3,1,3,3],'Z':[3,3,1,1]}

def transmit_char(c):
  if c in code:
    # transmit character
    for i in code[c]:
      transmitter.set_laserpulse(int(i)*dit)
      # break between symbols
      time.sleep(dit)
    # break between characters: 3 dits, 1 already made
    time.sleep(2*dit)
  elif c == ' ':
    # break between two words: 7 dits, (1+2)=3 already made
    time.sleep(4*dit)
  else:
    print(' Character ' + c + ' not in Morse code! ')

def valid_speed(speed):
  try:
    return int(speed) > 0 and int(speed) < 101
  except ValueError:
    return False

def setup_transmission_speed(dit):
  print ('\nSetting up speed of transmission to ' + str(round(1/dit)) + ' dits/s.\n')
  # send 5 pulses and 5 breaks of dit ms width to sync receiver
  for i in range(5):
    transmitter.set_laserpulse(dit)
    time.sleep(dit)
  # 0.5s break before transmission of data
  time.sleep(0.5)

print ('\n***** Morse Code Transmitter *****\n')

speed = input('Enter speed of transmission [1,100] dits/s: ')
while not valid_speed(speed):
  speed = input('Speed not valid, please reenter [1,100] dits/s: ')
dit = 1/int(speed)

# text to send via transmitter
text_out = input('\nEnter text to be transmitted: ')

# convert to uppercase
text_out = text_out.upper()

setup_transmission_speed(dit)

print ('***** Start of transmission *****\n')

index = 0
transmission_start = time.time()
for c in text_out:
  transmit_char(c)
  index = index +1
  # print character by character on screen
  sys.stdout.write(c)
  sys.stdout.flush()
  # new line on screen
  if index > 65 and c == ' ':
    index = 0
    print()
transmission_end = time.time()
print ('\n\n*****  End of transmission  *****\n')

print(str(len(text_out)) + ' characters transmitted in ' + str(round(transmission_end-transmission_start,2)) + ' s.')

print('\n*********************************')
